package gecko;

import gecko.lang.TypedMap;

import java.util.Objects;
import java.util.concurrent.CompletableFuture;

/**
 * @author 陈永佳 (yoojiachen@gmail.com)
 * @version 0.0.1
 */
public abstract class AbstractDevice extends AbstractHardware implements VirtualDevice {

    private TypedMap mInitArgs = TypedMap.empty();

    private FutureTransporter mFutureTransporter;

    @Override
    public void onInit(TypedMap initArgs, GeckoScoped scoped) {
        mInitArgs = initArgs;
    }

    @Override
    public void onStart(GeckoScoped scoped) {
        Objects.requireNonNull(mInitArgs, "onInit() not call");
    }

    @Override
    public void onStop(GeckoScoped scoped) {
        // nop
    }

    @Override
    public CompletableFuture<EventFrame> process(EventFrame event, GeckoScoped gs) throws Exception {
        // 默认情况下：
        // 远程虚拟设备，使用 FutureTransporter 接口来派发事件和获取响应。
        // 等待设备回复消息的时间，最大超时时间为5秒。
        if (mFutureTransporter != null) {
            return mFutureTransporter.transport(event, gs, getAddress(gs.getDomain(), gs.getNodeId()));
        } else {
            throw new UnsupportedOperationException("Should impl process() or set FutureTransporter");
        }
    }

    /**
     * @return 返回初始化参数
     */
    public TypedMap getInitArgs() {
        return mInitArgs;
    }

    /**
     * 设置 FutureTransporter 对象
     *
     * @param f FutureTransporter
     */
    public void setFutureTransporter(FutureTransporter f) {
        mFutureTransporter = f;
    }

    /**
     * @return 返回 FutureTransporter 对象；如果未设置，会抛出NPE异常；
     */
    protected FutureTransporter getCheckedFutureTransporter() {
        return Objects.requireNonNull(mFutureTransporter);
    }
}
